System Design_大型网站架构模式及核心要素

大型网站架构模式

所谓模式就是描述了在我们周围不断重复发生的问题以及该问题解决方案的核心,这样我们可以一次又一次使用该方案而不必重复解决问题。模式的关键在于模式的可重复性,问题与场景的可重复性带来解决方案的可重复使用。

为了解决大型网站面临的高并发访问、海量数据处理、高可靠运行等一系列问题与挑战,许多公司在实践中提出了许多解决方案,以实现网站高性能、高可用、易伸缩、可扩展、安全等技术架构目标。

分层

分层是企业应用系统常用的架构模式,将系统在横向维度切分为几个部分(垂直的分为几层),然后通过上层对下层的依赖和调用组成一个完整的系统,如分割为应用层、服务层、数据层,应用层可细分问u视图层、业务逻辑层。服务层可以细分为数据接口层、逻辑处理层。

不同层可以部署在不同的服务器上,实现低耦合,可伸缩。

分割

水平分割,例如按照功能将系统分割,包装为高内聚低耦合的模块单元,一方面有助于软件的开发和维护,同样便于不同模块的分布式部署,提高网站的并发处理能力和功能扩张能力。

分布式

对于大型网站,分层和分割的一个主要目的是为了切分后的模块便于分布式部署,可通过增加机器提高并发能力。但分布式需要通过网络,会带来性能的影响,多个服务器也意味着机器出现问题的概率变大,降低网站的可用性。另外一个问题是在分布式的环境中保持数据一致性。

几种分布式方案:

  1. 分布式应用和服务:将分层和分割后的应用和服务分布式部署,
  2. 分布式静态资源:将网站的静态资源独立分布式部署。
  3. 分布式数据和存储:分布式数据库,NoSQL等。
  4. 分布式计算

集群

使用分布式虽然已经将分层和分割后的模块独立部署,但是对于用户访问集中的模块,还需要将独立部署的服务器集群化,即多台服务器部署相同服务,通过负载均衡设备共同对外提供服务。通过添加新服务器可以提高服务能力,也就是具有可伸缩性,另外还可以通过失效转移等机制保证可用性。

缓存

  • CDN:内容分发网络,部署在离终端用户最近的网络服务提供商,缓存网站一些静态资源(变化较少的资源)或者热点内容。
  • 反向代理:反向代理属于网站前端架构的一部分,部署在网站的前端,当用户请求到达网站的数据中心时,最先访问的就是反向代理服务器,这里缓存网站的静态和热点资源,无需将请求转发给应用服务器就可以返回给用户。
  • 本地缓存:在应用服务器本地缓存热点数据,减少访问文件和数据库。
  • 分布式缓存:本地缓存一般不够大,另外将数据缓存在一个专门的分布式缓存集群中,通过网络通信访问缓存数据。

异步

降低软件耦合性,前面分层、分割、分布也是同样的目标。通过异步,业务之间的消息传递不是同步调用,而是将一个业务操作分成多个阶段,每个阶段之间通过共享数据的方式异步执行协作。

在单一服务器内部可通过多线程共享内存队列的方式实现异步:在分布式系统中,多个服务器可以通过分布式消息队列实现异步。

异步架构是典型的生产者消费者模式,两者不存在直接调用,只要保持数据结构不变,批次功能实现可以随意变化而不互相影响,这对网站扩展新功能非常便利。另外,使用异步消息队列还有如下特性。

提高系统可用性:消费者服务器发生故障,数据会在消息队列服务器中堆积,生产者可以继续处理业务请求,系统整体无故障。消费者服务器恢复正常后,继续处理消息队列中的数据。

加快网站相应速度:处在业务处理前端的生产者服务器可以在处理完业务请求后,将数据写入消息队列后返回,不需要同步等待消费者服务器处理就可以返回,减少相应延迟。

消除并发访问高峰:用户访问存在突然的高峰,如果同时同步处理所有访问,会导致网站负载过重,响应延迟。使用消息队列将突然增加的访问请求数据放入消息队列中,等待消费者服务器依次处理,就不会对整个网站负载造成太大压力。

冗余

要保证网站的可用性,需要一定程度的服务器冗余运行,数据冗余备份,这样当某台服务器宕机时,可以将其上的服务和数据访问转移到其他机器上。数据库除了冷备份外,为了保证在线业务高可用,也需要对数据库进行主从分离,实时同步实现热备份。

自动化

安全

大型网站核心要素

除了系统的功能需求外,软件架构还需要关注可能、可用性、伸缩性、扩展性、安全性这个5个架构要素,以及平衡这5个要素之间的关系以实现需求和架构目标。

性能

性能是网站的一个重要指标,用户无法忍受一个相应缓慢的网站。

性能的问题无处不在,所以优化的方面也很多:

  • 在浏览器端,可以通过浏览器缓存、页面压缩、减少cookie传输、JavaScript实现可以在本地实现的功能,减少访问次数
  • CDN,反向代理服务器缓存热点文件。
  • 应用服务器端,可以使用服务器本地缓存和分布式缓存,通过缓存在内存的热点数据,减少访问数据库,加快请求处理过程。
  • 异步将用户请求发送到消息队列等待处理,直接返回相应给用户。
  • 在高并发请求的情况下,可以将多台应用服务器组成一个集群共同对外服务,提高整体处理能力。
  • 代码层面,使用合适的数据结构、高效算法,以及多线程、改善内存管理等手段优化性能。
  • 数据库服务器端,索引、索引、sql优化。
  • NoSQL,Hadoop,分布式计算和存储。

衡量网站性能有一系列指标,如相应时间、TPS等,可以测试这些指标确定系统是否达到目标。

可用性

高可用架构设计的前提是必然出现服务器宕机,设计目标是服务器宕机时,服务依然可用。

实现高可用的主要手段是冗余,应用部署在多台服务器上同时提供服务,数据存储在多台服务器上相互备份,任何一台机器宕机不会影响整体服务,也不会导致数据丢失。

对于应用服务器,可以通过负载均衡服务器组成一个集群共同对外提供服务,一台机器宕机时可以将服务转移到其他机器上,前提是服务器不在本地保存服务的会话信息。

对于存储服务器,需要实现实时备份。

伸缩性

所谓伸缩性是指能否通过不断增加机器来缓解上升用户的并发访问压力和不断增长的数据存储需求。加入新的服务器后是否可以能提供和原来的服务器无差别的服务,集群中可容纳的总得服务器数量是否有限制。

对于应用服务器集群,只要服务器上不保存数据,所有服务器都是对等的,通过使用合适的负载均衡就可以向集群中不断加入服务器。

对于缓存服务器集群,加入新的服务其可能会导致缓存路由失效,进而导致集群中大部分缓存数据都无法访问。如果应用严重依赖缓存,可能对网站造成严重影响甚至数据库服务崩溃。需要改进缓存路由算法保证缓存数据的可访问性,一个解决方法是一致性hash算法。

关系数据库虽然支持数据复制,主从热备等机制,但是很难做到大规模集群的可伸缩性,因此关系数据库的集群伸缩方案必须在数据库之外实现,通过路由分区等手段将部署多个数据的服务器组成一个集群。

至于大部分NoSQL数据库产品,由于其就是为海量数据而生,所以对伸缩性支持都非常好,可以做到在较少操作下实现集群规模的线性伸缩。

扩展性

网站的扩展性架构直接关注网站的功能需求。网站快速发展,功能不断扩展,如何设计网站的架构使其能够快速相应需求变化,是网站可扩展的主要目的。

衡量网站架构扩展性的好坏的主要标准就是在网站增加新的业务产品时,是否可以实现对现有产品透明无影响,不需要改动或很少改动既有业务功能就可以上线新功能。不同产品之间是否很少耦合,一个产品改动对其他产品无影响。

网站可伸缩架构的主要手段是事件驱动和分布式服务。

事件驱动架构在网站使用消息队列实现,将用户请求和其他业务时间构造消息发布到消息队列,消息的处理作为消费者从消息队列中获取消息进行处理。通过这种方式将消息产生和消息处理分离开来,可以透明地增加新的消息生产者任务或者新的消息消费者任务。

分布式服务则是将业务和可复用的服务分离开来,通过分布式服务框架调用。新增产品可以调用可复用的服务实现自身的业务逻辑,而对现有产品没有任何影响。可复用服务升级变更时,也可以通过提供多版本服务对应用实现透明升级,不需要强制应用同步变更。

安全性

安全架构目的是保证网站不受恶意访问和攻击,保护网站的重要数据不被窃取。

衡量网站安全架构的标准就是针对现存和潜在的各种攻击和窃密手段,是否有可靠的应对策略。